/*

Copyright (C) 2010  Christoph Schnack 

    This file is part of Tribuit.

    Tribuit is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Tribuit is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Tribuit.  If not, see <http://www.gnu.org/licenses/>.
*/
package Settings;

import java.awt.Color;
import java.io.*;
import java.util.HashMap;
import java.util.Random;

import javax.swing.JOptionPane;
import javax.swing.UIManager;

import GuiTools.*;
import JukeBox.JukeBox;
import Storage.*;

/** 
 * 
 * This class contains the global settings values and their getter/setter methods. 
 * 
 * @author Christoph Schnack
 *
 */

public class Settings{
	private String[] KEYS = {     "language", "autosave", "soundOn", "firstStart",	"writeInLines",	"addToTray", "logoColors", 																"logoColorsRandom",							"backgroundColor", "bgcRandom","lookAndFeel",									"colorTheme",	"pictureIndexSegmentSize",	"wordCheckPresettings",	"createTADESettings",																																		"createTagSettings",																																											"evdLastVocabulary","volume",	"ctInt","ctIntValue",	"ctHexValue"};
	private String [] DEFAULTS = {"english",  "true",     "true",    "true",		"false",		"true",		 "160,240,5%160,240,5%160,240,5%160,240,5%160,240,5%160,240,5%160,240,5",	"false,false,false,false,false,false,false","0,0,0",		   "false",    UIManager.getCrossPlatformLookAndFeelClassName(),"default",		"0",						"null",					"rememberSettings:false,type:smallArrow,color:100;100;100,flashColor:255;0;0,defaultType:smallArrow,defaultColor:100;100;100,defaultFlashColor:255;0;0",	"rememberSettings:false,radius:8,shapeColor:0;0;0,fillColor:255;255;255,fillHlColor:255;0;0,defaultRadius:8,defaultShapeColor:0;0;0,defaultFillColor:255;255;255,defaultFillHlColor:255;0;0",	"",					"70",		"true",	"192",			"192"};
	private HashMap<String,String> SETUP = new HashMap<String,String>();
	private TribuitFrame MAINFRAME;
	private Storage MAINVOC;
	private Language LANG;
	private boolean VERBOSE;
	private TribuitTextField CURRENTTEXTFIELD;
	private TribuitLogger logger;
	private JukeBox jukeBox;
	
	public Settings(TribuitFrame tf,Storage voc,boolean verbose){
		MAINFRAME = tf;
		MAINVOC = voc;
		VERBOSE = verbose;
		logger = new TribuitLogger(MAINFRAME);
		for(UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()){
			if(laf.getName().equals("Nimbus"))DEFAULTS[10]= laf.getClassName();
		}
		load();
		jukeBox = new JukeBox(this);
	}
	
	public JukeBox getJukeBox(){
		return jukeBox;
	}
	
	public void logThrowable(Throwable t){
		logger.logException(t);
	}
	
	public boolean isVerbose(){ return VERBOSE;}
	
	public void setAutosave(boolean bool){
		if(bool){
			SETUP.put("autosave", "true");
		}
		else SETUP.put("autosave", "false");
	}
	
	public boolean getAutosave(){
		if(SETUP.get("autosave").equals("true")) return true;
		else return false;
	}
	
	public void setLanguage(String arg){
		SETUP.put("language",arg);
		loadLanguage();
	}
	
	public void setFirstStart(String arg){
		SETUP.put("firstStart", arg);
	}
	public boolean getFirstStart(){
		if(SETUP.get("firstStart").equals("true")) return true;
		else return false;
	}
	
	public boolean isSoundOn(){
		if(SETUP.get("soundOn").equals("true")) return true;
		else return false;
	}
	
	public void setSoundOn(boolean arg){
		if(arg) SETUP.put("soundOn","true");
		else SETUP.put("soundOn","false");
	}
	
	public boolean getWriteInLines(){
		if(SETUP.get("writeInLines").equals("true")) return true;
		else return false;
	}
	
	public void setWriteInLines(boolean arg){
		if(arg) SETUP.put("writeInLines","true");
		else SETUP.put("writeInLines","false");
	}
	
	
	public boolean getAddToSystemTray(){
		if(SETUP.get("addToTray").equals("true")) return true;
		else return false;
	}
	
	public void setAddToSystemTray(boolean arg){
		if(arg) SETUP.put("addToTray","true");
		else SETUP.put("addToTray","false");
	}
	
	public String getColorTheme(){
		return SETUP.get("colorTheme");
	}
	
	public void setColorTheme(String arg){
		SETUP.put("colorTheme",arg);
	}
	
	public boolean getBgColorRandom(){
		if(SETUP.get("bgcRandom").equals("true")) return true;
		else return false;
	}
	
	public void setBgColorRandom(boolean arg){
		if(arg) SETUP.put("bgcRandom","true");
		else SETUP.put("bgcRandom","false");
	}
	
	public Color getBackgroundColor(){
		String cols = SETUP.get("backgroundColor");
		String[] split=cols.split(",");
		return new Color(Integer.parseInt(split[0]),Integer.parseInt(split[1]),Integer.parseInt(split[2]));
	}
	
	public void setBackgroundColor(int r, int g, int b){
		SETUP.put("backgroundColor",r+","+g+","+b+",");
	}
	
	public boolean[] getLogoColorsRandom(){
		String cols = SETUP.get("logoColorsRandom");
		String[] splits=cols.split(",");
		boolean[] bools = new boolean[7];
		for(int i=0;i<7;i++){
			bools[i] = (splits[i].equals("true"))?true:false;
		}
		return bools;
	}
	
	public void setLogoColorsRandom(boolean[] arg){
		StringBuffer sb = new StringBuffer();
		for(int i=0;i<7;i++){
			sb.append((arg[i])?"true":"false");
			if(i<6)sb.append(",");
		}
		SETUP.put("logoColorsRandom", sb.toString());
	}
	
	public Color[] getLogoColors(){
		String cols = SETUP.get("logoColors");
		String[] splits=cols.split("%");
		Color[] mcs = new Color[7];
		for(int i=0;i<7;i++){
			String[] split = splits[i].split(",");
			mcs[i] = new Color(Integer.parseInt(split[0]),Integer.parseInt(split[1]),Integer.parseInt(split[2]));
		}
		return mcs;
	}
	
	public void setLogoColors(Color[] mcs){
		StringBuffer sb = new StringBuffer();
		for(int i=0;i<7;i++){
			sb.append(mcs[i].getRed()+","+mcs[i].getGreen()+","+mcs[i].getBlue());
			if(i<7) sb.append("%");
		}
		SETUP.put("logoColors",sb.toString());
	}
	
	public String getLookAndFeel(){
		return (SETUP.get("lookAndFeel"));
	}
	
	public void setLookAndFeel(String arg){
		if(arg!=null) SETUP.put("lookAndFeel",arg);
	}
	
	
	public String getCurrentLanguage(){
		return SETUP.get("language");
	}
	
	public Language getLanguage(){
		return LANG;
	}
	
	public boolean loadLanguage(){
		String loads = "";
		String name = SETUP.get("language");
		try{
		    File f = new File(GuiTools.TRIBUITHOME+File.separator+"settings"+File.separator+name+".lang");
		    BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(f),"UTF-8"));
	    	String line = null;
	    	while((line = reader.readLine()) != null){
	    		loads=loads+line;
	    	}
		}
		catch(Exception e){e.printStackTrace();}
		if(loads==null || loads.equals("")){
			return false;
		}
		else{
			LANG = new Language(loads.split(":"));
			return true;
		}
	}
	
	public void setup(String[] vals){
		SETUP = new HashMap<String,String>();
		for(int i = 0; i<vals.length;i++){
			SETUP.put(KEYS[i],vals[i]);
		}
		Random rnd = new Random();
		if(getBgColorRandom()){
			setBackgroundColor(rnd.nextInt(255),rnd.nextInt(255),rnd.nextInt(255));
		}
		StringBuffer sb = new StringBuffer();
		int i = 0;
		Color[] colors = getLogoColors();
		for(boolean b : getLogoColorsRandom()){
			if(b)sb.append(rnd.nextInt(255)+","+rnd.nextInt(255)+","+rnd.nextInt(255));
			else sb.append(colors[i].getRed()+","+colors[i].getGreen()+","+colors[i].getBlue());
			if(i++<6) sb.append("%");
		}
		SETUP.put("logoColors", sb.toString());
		this.setAutosave(this.getAutosave());
	}
	/*///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	 * START WordCheck-Section
	 */
	public HashMap<String,String> getWordCheckPresettings(){
		String load = SETUP.get("wordCheckPresettings");
		if(load!=null && !load.equals("null")){
			String[] split = load.split(",");
			String[] part;
			HashMap<String,String> hm = new HashMap<String, String>();
			for(String s : split){
				part = s.split(":");
				hm.put(part[0], part[1]);
			}
			return hm;
		}
		else return null;
	}
	
	public void setWordCheckPresettings(String s){
		SETUP.put("wordCheckPresettings", s);
	}
	
	/*
	 * END WordCheckPresettings-Section
	 *///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	/*///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	 * START CreateTag-Section
	 */
	public HashMap<String,String> getCreateTagSettings(){
		String load = SETUP.get("createTagSettings");
		if(load!=null){
			String[] split = load.split(",");
			String[] part;
			HashMap<String,String> result = new HashMap<String,String>();
			for(String s : split){
				part = s.split(":");
				result.put(part[0], part[1]);
			}
			return result;
		}
		return null;
	}
	
	public void setCreateTagSettings(HashMap<String,String> set){
		StringBuffer sb = new StringBuffer();
		String[] keys = set.keySet().toArray(new String[]{});
		for(int i=0;i<keys.length;i++){
			sb.append(keys[i]+":"+set.get(keys[i])+((i<(keys.length-1))?",":""));
		}
		SETUP.put("createTagSettings", sb.toString());
		save();
	}
	
	/*
	 * END CreateTag-Section
	 *///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	/*///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	 * START CreateTADESettingsSection
	 */
	public HashMap<String,String> getCreateTADESettings(){
		String load = SETUP.get("createTADESettings");
		if(load!=null){
			String[] split = load.split(",");
			String[] part;
			HashMap<String,String> hm = new HashMap<String, String>();
			for(String s : split){
				part = s.split(":");
				hm.put(part[0], part[1]);
			}
			return hm;
		}
		else return null;
	}
	
	public void setCreateTADESettings(HashMap<String,String> set){
		StringBuffer sb = new StringBuffer();
		String[] keys = set.keySet().toArray(new String[]{});
		for(int i=0;i<keys.length;i++){
			sb.append(keys[i]+":"+set.get(keys[i])+((i<(keys.length-1))?",":""));
		}
		SETUP.put("createTADESettings", sb.toString());
		save();
	}
	
	
	/*
	 * END CreateTADESettings-Section
	 *///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	
	/*///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	 * START PictureDescription-Section
	 */
	public int getPictureIndexSegmentSize(){
		return Integer.parseInt(SETUP.get("pictureIndexSegmentSize"));
	}
	public void setPictureIndexSegmentSize(String value){
		SETUP.put("pictureIndexSegmentSize", value);
	}
	/*
	 * END PictureDescription-Section
	 *///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	public String getEVDLastVocabulary(){
		return SETUP.get("evdLastVocabulary");
	}
	public void setEVDLastVocabulary(String value){
		SETUP.put("evdLastVocabulary", (value==null)?"":value);
	}
	
	public int getVolume(){
		return Integer.parseInt(SETUP.get("volume"));
	}
	public void setVolume(int value){
		SETUP.put("volume", (value>=0)?value+"":70+"");
		jukeBox = new JukeBox(this);
	}
	
	public boolean getCTIntegerSelected(){
		return SETUP.get("ctInt").equals("true");
	}
	public void setCTIntSelected(boolean arg){
		SETUP.put("ctInt", arg?"true":"false");
	}
	
	public int getCTIntValue(){
		return Integer.parseInt(SETUP.get("ctIntValue"));
	}
	public void setCTIntValue(int value){
		SETUP.put("ctIntValue", ""+value);
	}
	
	public int getCTHexValue(){
		return Integer.parseInt(SETUP.get("ctHexValue"));
	}
	public void setCTHexValue(int value){
		SETUP.put("ctHexValue", ""+value);
	}
	
	/**
	 * Fills setup with data from "Tribuit/settings/settings.set" or the DEFAULTS array.
	 * @author Christoph Schnack
	 */
	
	public void load(){
		StringBuffer loads = new StringBuffer();
		try{
		    File f = new File(GuiTools.TRIBUITHOME+File.separator+"settings"+File.separator+"settings.set");
	    	BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(f),"UTF-8"));
	    	String line = null;
	    	while((line = reader.readLine()) != null){
	    		loads.append(line);
	    	}
	    	if(loads.length()>0){
				setup(loads.toString().split("#"));
			}
			else setup(DEFAULTS);
	    	reader.close();
		}
		catch(Exception e){
			setup(DEFAULTS);
		}
		if(!loadLanguage()){
			JOptionPane.showMessageDialog(MAINFRAME,"Unable to load language file!","Error",JOptionPane.ERROR_MESSAGE);
			System.exit(0);
		}
	}
	
	public TribuitTextField getCurrentTextField(){
		return CURRENTTEXTFIELD;
	}
	
	public void setCurrentTextField(TribuitTextField tf){
		CURRENTTEXTFIELD=tf;
	}
	
	/**
	 * Writes the values from SETUP into "Tribuit/settings/settings.set". Generates it if necessary.
	 * 
	 * @author Christoph Schnack
	 */
	
	public boolean save(){
		try{
			BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(GuiTools.TRIBUITHOME+File.separator+"settings"+File.separator+"settings.set")),"UTF-8"));
			if(writer!=null){
				for(int i=0;i<KEYS.length;i++){
				    writer.write(SETUP.get(KEYS[i]));
				    writer.write("#");
				}
				writer.close();
				return true;
			}
		}
		catch(IOException e){}
		return false;
	}


	public void loadDefaults(){
		setup(DEFAULTS);
	}
}